package com.scalar.chiptrack.adaptor.ubicom.spil;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.HashMap;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Sep 18, 2007
 * Time: 6:17:41 PM
 */
public class SPILSortDataParser extends JobHandler implements AdaptorConstants
{

    HashMap m_sortBinDataMap = new HashMap();
    private Logger m_parserLogger = null;
    private String m_dataOutputDir = null;

    int waferidCount       = 0;
    int totalGoodDieQty     = 0;
    int totalProbeDieQty    = 0;

    public SPILSortDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_SPIL, WIP_TYPE_SORT);
            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_parserLogger = AdaptorUtils.getDataParserLogger(m_dataOutputDir, VENDOR_NAME_SPIL);
            FabSortAdaptorDAO.setLogger(m_parserLogger);
            AdaptorUtils.setLogger( m_parserLogger);
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading/creating SPIL output directory from database, Exception: " + se);
            throw se;
        }
    }

    public static void main(String args[]) throws Exception
    {
        try
        {
            new SPILSortDataParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    public void execute() throws Exception
    {
        AdaptorUtils.printHeader("SPIL SORT FTP", CONSTANT_PARSER );

        File doneDestDir = new File(m_dataOutputDir + "/done");

       File wipDataoutDir = new File(m_dataOutputDir);


       File[] fileList = wipDataoutDir.listFiles();

       if ((fileList == null) || (fileList.length <= 3))
       {
           log("No file found in directory: " + wipDataoutDir);
           throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
       }

        int adaptor_id1 = AdaptorRunInfo.getLastRunAdaptorId( SPILFTPSortAdaptor.ADAPTOR_NAME1, CONSTANT_ADAPTOR);
        int adaptor_id2 = AdaptorRunInfo.getLastRunAdaptorId( SPILFTPSortAdaptor.ADAPTOR_NAME2, CONSTANT_ADAPTOR);

        ArrayList sortlotbinList    = null;
        ArrayList successFileList   = new ArrayList();
        String fileName             = null;
        boolean success             = true;

        for (int i = 0; i < fileList.length; i++)
        {
            if (fileList[i].isDirectory() == true)
            {
                continue;
            }

            fileName = fileList[i].getAbsolutePath();

            try
            {
                // Step 1
                // Parse Files to get Object List
                if (fileList[i].getName() != null && fileList[i].getName().startsWith(SPILFTPSortAdaptor.FILE_NAME_SORT_WIP))
                {
                    sortlotbinList = parseSortLotBinReport(fileName);

                    //To get the Sort Binning information
                    getSortBinDetails(sortlotbinList);
                    waferidCount = 0;
                    totalProbeDieQty = 0;
                    totalGoodDieQty = 0;

                    successFileList.add(fileList[i]);
                }
            }
            catch (Exception e)
            {
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id1 );
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id2 );
                success = false;
                log("Exception while parsing and storing file: " + fileName + "\nException: " + e);
                e.printStackTrace();
                throw e;
            }
        }

        try
        {
            if (m_sortBinDataMap.isEmpty() == false)
            {
               FabSortAdaptorDAO.saveSortBinData(null, m_sortBinDataMap.values().iterator());
            }
            m_sortBinDataMap.clear();
        }
        catch (Exception e)
        {
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id1 );
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id2 );
            success = false;
            System.out.println(" Exception Occrred While Saving the Sort Binning Info " + e);
            throw e;
        }

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_SPIL, true, true, true );

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SPILFTPSortAdaptor.ADAPTOR_NAME1, CONSTANT_SUCCESS, adaptor_id1);
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SPILFTPSortAdaptor.ADAPTOR_NAME2, CONSTANT_SUCCESS, adaptor_id2);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SPILFTPSortAdaptor.ADAPTOR_NAME1, CONSTANT_SUCCESS, adaptor_id1);
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SPILFTPSortAdaptor.ADAPTOR_NAME2, CONSTANT_SUCCESS, adaptor_id2);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    } // end of execute method.


    private ArrayList parseSortLotBinReport(String fileName) throws Exception
    {
        ArrayList lotbinList = new ArrayList();
        SPILSortBinReport sortBinReport = null;
        if (fileName == null) throw new ScalarException("Filename argument is null");

        // Phase-I variables
        File lotbinFile = new File(fileName);

        if (lotbinFile.exists() == false)
        {
            throw new ScalarException(fileName + " doesnt exist");
        }
        /*Added code to ignoring the file, if file is empty*/
        if (lotbinFile.length() == 0)
        {
            return lotbinList;
        }

        String DEVICE   = "A. Device      :";
        String LOTNO    = "B. Lot No#     :";
        String DATE     = "H. Start Date  :";

        String deviceName   = null;
        String lotNo        = null;
        String waferId      = null;
        String dateIn       = null;
        String tester       = null;
        String testPgm      = null;
        String line         = null;


        String LINE_STARTS_WITH = "ID";
        String LINE_ENDS_WITH = "==> Lot BinCount & Yield";

        BufferedReader bReader = null;

        try
        {
            bReader = new BufferedReader(new FileReader(lotbinFile));

            while ((line = bReader.readLine()) != null)
            {
                line = line.trim();
                if (line.indexOf(DEVICE) != -1)
                {
                    deviceName = line.substring(DEVICE.length()).trim();
                }
                if (line.indexOf(LOTNO) != -1)
                {
                    lotNo = line.substring(LOTNO.length()).trim();
                }
                if (line.indexOf(DATE) != -1)
                {
                    dateIn = line.substring(DATE.length()).trim();
                    dateIn = StringUtils.formatDate(dateIn, "yyyy/MM/dd", "MM/dd/yyyy");
                }
                if (line.indexOf("C. Tester      :") != -1)
                {
                    tester = line.substring("C. Tester      :".length()).trim();
                }
                if (line.indexOf("G. Program     :") != -1)
                {
                    testPgm = line.substring("G. Program     :".length()).trim();
                    testPgm = testPgm.substring(testPgm.indexOf("_") + 1 , testPgm.lastIndexOf(".") );

                }

            }
            bReader.close();
            bReader = null;
            line = null;


            bReader = new BufferedReader(new FileReader(lotbinFile));


         /*   **********  wafer map  **********

            1. Wafer ID        :  NA4140-01
            2. Die per Wafer   :  2507
            3. Start Time      :  2006/11/08 08:15:37
            4. End Time        :  2006/11/08 09:08:37
            5. BinCount & Yield:

            bin  1 bin  8 bin  9 bin 10 bin 11 bin 12 bin 15 bin 20 bin 21 bin 25 bin 30 bin 35 bin 36 bin 40 bin 45 bin 50 bin 55 bin 60 bin 65 bin 70
              2350      0      0      2      0      0     31      0      0      1      0      5      0     20      1      4      1      4      0      1
            93.74% 00.00% 00.00% 00.08% 00.00% 00.00% 01.24% 00.00% 00.00% 00.04% 00.00% 00.20% 00.00% 00.80% 00.04% 00.16% 00.04% 00.16% 00.00% 00.04%

            6. Bincode Map in Hex Format :  */


            while ((line = bReader.readLine()) != null)
            {
                line = line.trim();

                if (line.startsWith(LINE_STARTS_WITH) )
                {
                    line = bReader.readLine();
                    line = line.trim();

                    while( ( line = bReader.readLine() ) != null && (!line.startsWith("-------") && (!line.startsWith(LINE_ENDS_WITH) )) )
                    {
                        sortBinReport = new SPILSortBinReport();

                        waferId = line.substring(12, 15 );
                        String waferQtyIn = line.substring(17, 22);
                        int totalQtyIndex = 0;
                        totalQtyIndex = line.indexOf("%");
                        String totalWaferQuantityIn = line.substring(totalQtyIndex -13, totalQtyIndex - 8);
                        String waferYield = line.substring(totalQtyIndex - 7, totalQtyIndex);

                        int qtyIn = 0;
                        if( waferQtyIn != null && waferQtyIn.trim().length() > 0 )
                        {
                            try
                            {
                                qtyIn = Integer.parseInt(waferQtyIn.trim());
                            }
                            catch(NumberFormatException e)
                            {
                               e.printStackTrace();
                            }
                        }

                        int totalWaferQtyIn = 0;
                        if( waferQtyIn != null && waferQtyIn.trim().length() > 0 )
                        {
                            try
                            {
                                totalWaferQtyIn = Integer.parseInt(totalWaferQuantityIn.trim());
                            }
                            catch(NumberFormatException e)
                            {
                               e.printStackTrace();
                            }
                        }

                        float yield = 0.0f;
                        if (waferQtyIn != null && waferQtyIn.trim().length() > 0)
                        {
                            try
                            {
                                yield = Float.parseFloat(waferYield.trim());
                            }
                            catch (NumberFormatException e) {
                                e.printStackTrace();
                            }
                        }


                        int rejQtyIn = 0;

                        rejQtyIn = totalWaferQtyIn - qtyIn;

                        totalGoodDieQty = totalGoodDieQty + qtyIn;
                        totalProbeDieQty = totalProbeDieQty + totalWaferQtyIn;
                        waferidCount = waferidCount + 1;

                        if( lotNo != null && deviceName != null && qtyIn > 0 )
                        {
                            sortBinReport.setWaferId( waferId);
                            sortBinReport.setGoodBinQtyIn(qtyIn);
                            sortBinReport.setDeviceName(deviceName);
                            sortBinReport.setDateIn(dateIn);
                            sortBinReport.setLotNumber(lotNo);
                            sortBinReport.setRejectedBinQtyIn(rejQtyIn);
                            sortBinReport.setTester(tester);
                            sortBinReport.setTestPgm(testPgm);
                            sortBinReport.setQtyIn(totalWaferQtyIn);
                            sortBinReport.setYield(yield);
                            lotbinList.add(sortBinReport);
                        }
                    }
                }
            }
        }

        catch (Exception e)
        {
            System.out.println("Exception while parsing SPIL Sort Bin information \n" + e + "\n");
            throw e;
        }

        return lotbinList;
    }


    private void getSortBinDetails( ArrayList sortBinList )  throws Exception
    {
        if ( sortBinList == null || sortBinList.size() == 0 )
        {
           log( "No Sort Bin Lots when the List is Empty");
           return;
        }
        SPILSortBinReport sortbinReport  = null;
        String diepartNumber                = null;
        String lotNumber                    = null;
        String waferId                      = null;
        ArrayList releaseLotsList           = null;
        FabSortLot  sortBinLot              = null;

        try
        {
            Iterator iterator = sortBinList.iterator();

            while ( iterator.hasNext() )
            {
                sortbinReport = ( SPILSortBinReport )iterator.next() ;

                lotNumber  = sortbinReport.getLotNumber();
                waferId    = sortbinReport.getWaferId();
                diepartNumber = sortbinReport.getDeviceName();

                if ( diepartNumber != null && lotNumber != null && waferId != null )
                {
                    sortBinLot = ( FabSortLot ) m_sortBinDataMap.get( diepartNumber + lotNumber + waferId );

                    if ( sortBinLot == null )
                    {
                        sortBinLot = new FabSortLot( VENDOR_NAME_SPIL , LOCATION_TYPE_SORT );
                        m_sortBinDataMap.put( diepartNumber + lotNumber + waferId , sortBinLot );
                    }

                    sortBinLot.setCustProduct( diepartNumber );
                    sortBinLot.setLotId( lotNumber );
                    sortBinLot.setWaferID( waferId );
                     // WAFER QTY IN Always Same(total wafers) ,But For Each every Wafer update the Wafer Qty, the the WaferQty
                    sortBinLot.setQtyIn( waferidCount +"" );
                    sortBinLot.setDateIn( sortbinReport.getDateIn() );
                    sortBinLot.setTotalgoodDieQtyIn( totalGoodDieQty );
                    sortBinLot.setTotalprobeQtyIn( totalProbeDieQty );
                    sortBinLot.setTestProgram( sortbinReport.getTestPgm() );
                    sortBinLot.setTesterNo( sortbinReport.getTester() );
                    sortBinLot.setGoodDieQtyIn(sortbinReport.getGoodBinQtyIn());
                    sortBinLot.setRejectedQtyIn(sortbinReport.getRejectedBinQtyIn());
                    sortBinLot.setShipYield(sortbinReport.getYield()+"");
                    sortBinLot.setBinNumber( "Bin1");
                }
            }
        }
        catch(Exception e )
        {
            throw new ScalarException("Exception occured while parsing the Sort Bin Inforamtion" +e );
        }
    }
    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logDebug( message + LINE_SEPARATOR );
        }
        else
        {
            System.out.println( message );
        }
    } // end of log method

}
